package linc.fun.openai.manager;

import cn.hutool.core.collection.CollUtil;
import jakarta.annotation.Resource;
import linc.fun.openai.constants.RedisKeyConstants;
import linc.fun.openai.domain.entity.chat.ChatOrderItemDO;
import linc.fun.openai.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author yqlin
 * @date 2023/5/17 22:54
 * @description
 */
@Component
@Slf4j
public class ChatProductStockManager {
    @Resource
    private Redisson redisson;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 归还商品预库存
     */
    public void returnProductStock(List<ChatOrderItemDO> orderItems) {
        if (CollUtil.isEmpty(orderItems)) {
            throw BizException.DATA_HAS_BEEN_LOOSED;
        }
        for (ChatOrderItemDO orderItem : orderItems) {
            Long productId = orderItem.getProductId();
            RLock rLock = redisson.getLock(RedisKeyConstants.INCREASE_CHAT_PRODUCT_STOCK_LOCK_KEY + productId);
            try {
                boolean tryLock = rLock.tryLock(1, 5 * 60, TimeUnit.SECONDS);
                if (tryLock) {
                    redisTemplate.opsForHash().increment(RedisKeyConstants.CHAT_PRODUCT_ID_STOCK_KEY, productId.toString(), orderItem.getExchangeNum());
                    log.info("订单号: {},商品ID: {}，商品名称: {}，回退预库存: {}，回退后的库存为: {}",
                            orderItem.getOrderId(),
                            orderItem.getProductId(),
                            orderItem.getProductName(),
                            orderItem.getExchangeNum(),
                            redisTemplate.opsForHash().get(RedisKeyConstants.CHAT_PRODUCT_ID_STOCK_KEY, productId.toString())
                    );
                }
            } catch (Exception ex) {
                log.error("归还库存异常", ex);
            } finally {
                if (Objects.nonNull(rLock) &&
                        rLock.isLocked() &&
                        rLock.isHeldByCurrentThread()) {
                    rLock.unlock();
                }
            }
        }
    }
}
